//    entity language compiler Copyright (C) 2011 Vincent Belliard

//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation version 3 of the License.

//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.

//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.

class T_scope ;
class T_expression_identifier_access ;
class T_expression_call_access ;
class T_expression_local ;
class T_prototype_argument ;
class T_object_class_value ;

class T_expression : public LINK<T_expression>
	{
public:
	T_entity_location location ;
	T_type *type ;
	int dead ;
	int test ;
	int instruction ;
	T_expression(const T_entity_location &new_location) : location(new_location) { type = NULL ; dead = FALSE ; test = FALSE ; instruction = FALSE ; }
	virtual ~T_expression() {}
	virtual const char *get_name(void) const = 0 ;
	virtual void dump(FILE *file) const = 0 ;
	virtual int is_block(void) const { return FALSE ; }
	virtual int is_native(void) const { return FALSE ; }
	virtual T_type *get_type_expression(void) const { return NULL ; }
	virtual int search_field(T_entity_program *program, const T_string name, T_expression_identifier_access *identifier_access) ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) { compiler->add_error(location, "NI : %s : semantic not defined.", get_name()) ; return FALSE ; }
	virtual int verify_call_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type, T_expression_call_access *call) { compiler->add_error(location, "NI : %s : call_semantic not defined.", get_name()) ; return FALSE ; }
	virtual void prepare(T_entity_program *program, FILE *file) {}
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) { fprintf(stderr, "NI : %s : generate not defined.\n", get_name()) ; }
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) { fprintf(stderr, "NI : %s : generate_test not defined.<%.40s>\n", get_name(), location.location.get_from()) ; fprintf(file, "NI : %s : generate_test\n", get_name()) ; }
	virtual void generate_instruction(T_entity_program *program, FILE *file) { fprintf(stderr, "NI : %s : generate_instruction not defined.\n", get_name()) ; }
	virtual void prepare_call(T_entity_program *program, FILE *file, const T_expression_call_access *call) {}
	virtual void generate_call(T_entity_program *program, FILE *file, const T_expression_call_access *call) { fprintf(stderr, "NI : %s : generate_call not defined.\n", get_name()) ; }
	virtual void generate_constructor(T_entity_program *program, FILE *file, const T_string name) { fprintf(stderr, "NI : %s : generate_constructor not defined.\n", get_name()) ; }
	virtual void generate_constructor(T_entity_program *program, FILE *file, const T_string name, const T_expression_call_access *call) { fprintf(stderr, "NI : %s : generate_constructor for call not defined.\n", get_name()) ; }
	} ;

class T_expression_block : public T_expression
	{
public:
	LIST<T_expression> expressions ;
	T_expression_block(const T_entity_location &new_location) : T_expression(new_location) {}
	virtual const char *get_name(void) const { return "block" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return TRUE ; }
	void parse(T_entity_compiler *compiler) ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	} ;

class T_expression_integer : public T_expression
	{
public:
	unsigned long long value ;
	T_expression_integer(const T_entity_location &new_location, unsigned long long new_value) : T_expression(new_location) { value = new_value ; }
	virtual const char *get_name(void) const { return "integer" ; }
	virtual void dump(FILE *file) const ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	} ;

class T_expression_string : public T_expression
	{
public:
	T_string value ;
	int index ;
	T_expression_string(const T_entity_location &new_location, const T_string &new_value) : T_expression(new_location), value(new_value) { index = 0 ; }
	virtual const char *get_name(void) const { return "string" ; }
	virtual void dump(FILE *file) const ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void prepare(T_entity_program *program, FILE *file) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	} ;

class T_expression_identifier : public T_expression
	{
public:
	T_string value ;
	T_object_class *object_class ;
	const T_constructor *constructor ;
	T_global *global ;
	T_expression_local *local ;
	T_prototype_argument *argument ;
	const T_object_class_method *method ;
	const T_object_class_field *field ;
	T_expression_identifier(const T_entity_location &new_location, const T_string &new_value) : T_expression(new_location), value(new_value) { object_class = NULL ; constructor = NULL ; global = NULL ; local = NULL ; argument = NULL ; method = NULL ; field = NULL ; }
	virtual T_type *get_type_expression(void) const { return (object_class == NULL) ? NULL : new T_type_identifier(location, object_class) ; }
	virtual const char *get_name(void) const { return "identifier" ; }
	virtual void dump(FILE *file) const ;
	virtual int search_field(T_entity_program *program, const T_string name, T_expression_identifier_access *identifier_access) ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual int verify_call_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type, T_expression_call_access *call) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	virtual void prepare_call(T_entity_program *program, FILE *file, const T_expression_call_access *call) ;
	virtual void generate_call(T_entity_program *program, FILE *file, const T_expression_call_access *call) ;
	virtual void generate_constructor(T_entity_program *program, FILE *file, const T_string name) ;
	virtual void generate_constructor(T_entity_program *program, FILE *file, const T_string name, const T_expression_call_access *call) ;
	} ;

class T_expression_boolean : public T_expression
	{
public:
	int value ;
	T_expression_boolean(const T_entity_location &new_location, int new_value) : T_expression(new_location) { value = new_value ; }
	virtual const char *get_name(void) const { return "boolean" ; }
	virtual void dump(FILE *file) const ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	} ;

class T_expression_null : public T_expression
	{
public:
	T_expression_null(const T_entity_location &new_location) : T_expression(new_location) {}
	virtual const char *get_name(void) const { return "null" ; }
	virtual void dump(FILE *file) const ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	} ;

class T_expression_character : public T_expression
	{
public:
	unsigned long value ;
	T_expression_character(const T_entity_location &new_location, unsigned long new_value) : T_expression(new_location) { value = new_value ; }
	virtual const char *get_name(void) const { return "character" ; }
	virtual void dump(FILE *file) const ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	} ;

class T_expression_type : public T_expression
	{
public:
	T_type *type_value ;
	T_expression_type(const T_entity_location &new_location, T_type *new_type_value) : T_expression(new_location) { type_value = new_type_value ; }
	virtual ~T_expression_type() { delete type_value ; }
	virtual T_type *get_type_expression(void) const { return type_value ; }
	virtual const char *get_name(void) const { return "type" ; }
	virtual void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	} ;

class T_expression_vector : public T_expression
	{
public:
	LIST<T_expression> expressions ;
	int index ;
	T_expression_vector(const T_entity_location &new_location) : T_expression(new_location) { index = 0 ; }
	virtual const char *get_name(void) const { return "vector" ; }
	virtual void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void prepare(T_entity_program *program, FILE *file) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	} ;

#define expression_native_entity 1
#define expression_native_cpp 2

class T_expression_native : public T_expression
	{
public:
	int type ;
	T_string value ;
	T_expression_native(const T_entity_location &new_location, int new_type) : T_expression(new_location) { type = new_type ; }
	virtual ~T_expression_native() {}
	virtual int is_block(void) const { return TRUE ; }
	virtual int is_native(void) const { return TRUE ; }
	virtual const char *get_name(void) const { return "native" ; }
	virtual void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	int parse_block(T_entity_compiler *compiler) ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) { return TRUE ; }
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	} ;

class T_expression_local : public T_expression
	{
public:
	int constant ;
	T_string name ;
	T_expression *type_expression ;
	T_type *type_value ;
	T_expression *expression ;
	T_expression_local(const T_entity_location &new_location, int new_constant) : T_expression(new_location) { constant = new_constant ; type_expression = NULL ; type_value = NULL ; expression = NULL ; }
	virtual ~T_expression_local() { if (type != NULL) delete type ; if (expression != NULL) delete expression ; }
	int is_reference(void) const { return type_value->is_reference() ; }
	virtual const char *get_name(void) const { return "local" ; }
	virtual void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	virtual int is_block(void) const { return (expression != NULL) && expression->is_block() ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	} ;

class T_expression_constructor_arguments : public T_expression
	{
public:
	LIST<T_expression> expressions ;
	T_expression_constructor_arguments(const T_entity_location &new_location) : T_expression(new_location) {}
	} ;

class T_expression_new : public T_expression_constructor_arguments
	{
public:
	T_string name ;
	T_object_class *object_class ;
	const T_constructor *constructor ;
	int index ;
	T_expression_new(const T_entity_location &new_location) : T_expression_constructor_arguments(new_location) { object_class = NULL ; constructor = NULL ; index = 0 ; }
	virtual T_type *get_type_expression(void) const { return type ; }
	virtual const char *get_name(void) const { return "new" ; }
	virtual void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void prepare(T_entity_program *program, FILE *file) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	} ;

class T_expression_if_item : public LINK<T_expression_if_item>
	{
public:
	T_expression *condition ;
	T_expression *expression ;
	T_expression_if_item(T_expression *new_condition, T_expression *new_expression) { condition = new_condition ; expression = new_expression ; }
	virtual ~T_expression_if_item() { delete condition ; delete expression ; }
	} ;

class T_expression_if : public T_expression
	{
public:
	LIST<T_expression_if_item> items ;
	T_expression *else_expression ;
	T_expression_if(const T_entity_location &new_location) : T_expression(new_location) { else_expression = NULL ; }
	virtual ~T_expression_if() { if (else_expression != NULL) delete else_expression ; }
	virtual const char *get_name(void) const { return "if" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return (else_expression != NULL) ? else_expression->is_block() : ((items.last != NULL) ? items.last->expression->is_block() : FALSE) ; }
	void parse(T_entity_compiler *compiler) ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	} ;

class T_expression_loop : public T_expression
	{
public:
	T_string name ;
	T_expression *expression ;
	T_expression_loop(const T_entity_location &new_location) : T_expression(new_location) { expression = NULL ; }
	virtual ~T_expression_loop() { if (expression != NULL) delete expression ; }
	virtual const char *get_name(void) const { return "loop" ; }
	virtual void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	virtual int is_block(void) const { return expression->is_block() ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	} ;

class T_expression_while : public T_expression_loop
	{
public:
	T_expression *condition ;
	int index ;
	T_expression_while(const T_entity_location &new_location) : T_expression_loop(new_location) { condition = NULL ; index = 0 ; }
	virtual ~T_expression_while() { if (condition != NULL) delete condition ; }
	virtual const char *get_name(void) const { return "while" ; }
	virtual void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	virtual int is_block(void) const { return expression->is_block() ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	} ;

class T_expression_leave : public T_expression
	{
public:
	T_string name ;
	T_expression *expression ;
	T_expression_leave(const T_entity_location &new_location) : T_expression(new_location) { expression = NULL ; }
	virtual ~T_expression_leave() { if (expression != NULL) delete expression ; }
	virtual const char *get_name(void) const { return "leave" ; }
	virtual void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	virtual int is_block(void) const { return (expression != NULL) && expression->is_block() ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	} ;

class T_expression_return : public T_expression
	{
public:
	T_expression *expression ;
	T_type *method_returned_type ;
	T_expression_return(const T_entity_location &new_location) : T_expression(new_location) { expression = NULL ; method_returned_type = NULL ; }
	virtual ~T_expression_return() { if (expression != NULL) delete expression ; }
	virtual const char *get_name(void) const { return "return" ; }
	virtual void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	virtual int is_block(void) const { return (expression != NULL) && expression->is_block() ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	} ;

class T_expression_compute : public T_expression
	{
public:
	T_expression *value ;
	T_expression *expression ;
	int index ;
	T_expression_compute(const T_entity_location &new_location) : T_expression(new_location) { value = NULL ; expression = NULL ; index = 0 ; }
	virtual const char *get_name(void) const { return "compute" ; }
	virtual void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	virtual int is_block(void) const { return expression->is_block() ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	} ;

class T_expression_case : public T_expression
	{
public:
	T_expression *expression ;
	T_expression_compute *compute ;
	T_expression_case(const T_entity_location &new_location) : T_expression(new_location) { expression = NULL ; }
	virtual ~T_expression_case() { if (expression != NULL) delete expression ; }
	virtual const char *get_name(void) const { return "case" ; }
	virtual void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	virtual int is_block(void) const { return expression->is_block() ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	} ;

class T_expression_test_or : public T_expression
	{
public:
	LIST<T_expression> expressions ;
	T_expression_test_or(const T_entity_location &new_location) : T_expression(new_location) {}
	virtual const char *get_name(void) const { return "test_or" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return expressions.last->is_block() ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	} ;

class T_expression_test_and : public T_expression
	{
public:
	LIST<T_expression> expressions ;
	T_expression_test_and(const T_entity_location &new_location, T_expression *new_expression) : T_expression(new_location) { expressions.insert(new_expression) ; }
	virtual const char *get_name(void) const { return "test_and" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return expressions.last->is_block() ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	} ;

class T_expression_test : public T_expression
	{
public:
	T_expression *expression ;
	T_expression_test(const T_entity_location &new_location, T_expression *new_expression) : T_expression(new_location) { expression = new_expression ; }
	virtual ~T_expression_test() { delete expression ; }
	virtual const char *get_name(void) const { return "test" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return expression->is_block() ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	} ;

class T_expression_success : public T_expression
	{
public:
	T_expression_success(const T_entity_location &new_location) : T_expression(new_location) {}
	virtual ~T_expression_success() {}
	virtual const char *get_name(void) const { return "success" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return FALSE ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	} ;

enum T_expression_assign_type
	{
	expression_assign_type_assign,
	expression_assign_type_add,
	expression_assign_type_substract,
	expression_assign_type_multiply,
	expression_assign_type_divide,
	expression_assign_type_modulo,
	expression_assign_type_and,
	expression_assign_type_exclusive_or,
	expression_assign_type_or,
	expression_assign_type_left_shift,
	expression_assign_type_right_shift
	} ;

class T_expression_assign : public T_expression
	{
public:
	T_expression *destination ;
	T_expression_assign_type assign_type ;
	T_expression *expression ;
	T_expression_assign(const T_entity_location &new_location, T_expression *new_destination, T_expression_assign_type new_assign_type) : T_expression(new_location) { destination = new_destination ; assign_type = new_assign_type ; expression = NULL ; }
	virtual ~T_expression_assign() { delete destination ; if (expression != NULL) delete expression ; }
	virtual const char *get_name(void) const { return "assign" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return expression->is_block() ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void prepare(T_entity_program *program, FILE *file) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	} ;

class T_expression_logical_or : public T_expression
	{
public:
	LIST<T_expression> expressions ;
	T_expression_logical_or(const T_entity_location &new_location, T_expression *new_expression) : T_expression(new_location) { expressions.insert(new_expression) ; }
	virtual const char *get_name(void) const { return "logical_or" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return expressions.last->is_block() ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	} ;

class T_expression_logical_and : public T_expression
	{
public:
	LIST<T_expression> expressions ;
	T_expression_logical_and(const T_entity_location &new_location, T_expression *new_expression) : T_expression(new_location) { expressions.insert(new_expression) ; }
	virtual const char *get_name(void) const { return "logical_and" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return expressions.last->is_block() ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	} ;

enum T_expression_comparison_type
	{
	expression_comparison_type_equal,
	expression_comparison_type_not_equal,
	expression_comparison_type_less,
	expression_comparison_type_less_or_equal,
	expression_comparison_type_greater,
	expression_comparison_type_greater_or_equal
	} ;

class T_expression_comparison : public T_expression
	{
public:
	T_expression *left ;
	T_expression_comparison_type comparison_type ;
	T_expression *right ;
	T_expression_comparison(const T_entity_location &new_location, T_expression *new_left, T_expression_comparison_type new_comparison_type) : T_expression(new_location) { left = new_left ; comparison_type = new_comparison_type ; right = NULL ; }
	virtual ~T_expression_comparison() { delete left ; if (right != NULL) delete right ; }
	virtual const char *get_name(void) const { return "comparison" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return right->is_block() ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	} ;

class T_expression_arithmetic_or : public T_expression
	{
public:
	LIST<T_expression> expressions ;
	T_expression_arithmetic_or(const T_entity_location &new_location, T_expression *new_expression) : T_expression(new_location) { expressions.insert(new_expression) ; }
	virtual const char *get_name(void) const { return "arithmetic_or" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return expressions.last->is_block() ; }
	} ;

class T_expression_arithmetic_xor : public T_expression
	{
public:
	LIST<T_expression> expressions ;
	T_expression_arithmetic_xor(const T_entity_location &new_location, T_expression *new_expression) : T_expression(new_location) { expressions.insert(new_expression) ; }
	virtual const char *get_name(void) const { return "arithmetic_xor" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return expressions.last->is_block() ; }
	} ;

class T_expression_arithmetic_and : public T_expression
	{
public:
	LIST<T_expression> expressions ;
	T_expression_arithmetic_and(const T_entity_location &new_location, T_expression *new_expression) : T_expression(new_location) { expressions.insert(new_expression) ; }
	virtual const char *get_name(void) const { return "arithmetic_and" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return expressions.last->is_block() ; }
	} ;

class T_expression_shift_left : public T_expression
	{
public:
	T_expression *left ;
	T_expression *right ;
	T_expression_shift_left(const T_entity_location &new_location, T_expression *new_left) : T_expression(new_location) { left = new_left ; right = NULL ; }
	virtual ~T_expression_shift_left() { delete left ; delete right ; }
	virtual const char *get_name(void) const { return "shift_left" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return right->is_block() ; }
	} ;

class T_expression_shift_right : public T_expression
	{
public:
	T_expression *left ;
	T_expression *right ;
	T_expression_shift_right(const T_entity_location &new_location, T_expression *new_left) : T_expression(new_location) { left = new_left ; right = NULL ; }
	virtual ~T_expression_shift_right() { delete left ; delete right ; }
	virtual const char *get_name(void) const { return "shift_right" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return right->is_block() ; }
	} ;

enum T_expression_additive_type { expression_additive_type_addition, expression_additive_type_substraction } ;

class T_expression_additive_item : public LINK<T_expression_additive_item>
	{
public:
	T_expression_additive_type type ;
	T_expression *expression ;
	T_expression_additive_item(T_expression_additive_type new_type, T_expression *new_expression) { type = new_type ; expression = new_expression ; }
	virtual ~T_expression_additive_item() { delete expression ; }
	} ;

class T_expression_additive : public T_expression
	{
public:
	T_expression *expression ;
	LIST<T_expression_additive_item> items ;
	T_expression_additive(const T_entity_location &new_location, T_expression *new_expression) : T_expression(new_location) { expression = new_expression ; }
	virtual const char *get_name(void) const { return "additive" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return items.last->expression->is_block() ; }
	void parse(T_entity_compiler *compiler) ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void prepare(T_entity_program *program, FILE *file) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	} ;

enum T_expression_multiplicative_type { expression_multiplicative_type_multiplication, expression_multiplicative_type_division, expression_multiplicative_type_modulus } ;

class T_expression_multiplicative_item : public LINK<T_expression_multiplicative_item>
	{
public:
	T_expression_multiplicative_type type ;
	T_expression *expression ;
	T_expression_multiplicative_item(T_expression_multiplicative_type new_type, T_expression *new_expression) { type = new_type ; expression = new_expression ; }
	virtual ~T_expression_multiplicative_item() { delete expression ; }
	} ;

class T_expression_multiplicative : public T_expression
	{
public:
	T_expression *expression ;
	LIST<T_expression_multiplicative_item> items ;
	T_expression_multiplicative(const T_entity_location &new_location, T_expression *new_expression) : T_expression(new_location) { expression = new_expression ; }
	virtual const char *get_name(void) const { return "multiplicative" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return items.last->expression->is_block() ; }
	void parse(T_entity_compiler *compiler) ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void prepare(T_entity_program *program, FILE *file) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	} ;

class T_expression_unary : public T_expression
	{
public:
	T_expression *expression ;
	T_expression_unary(const T_entity_location &new_location, T_expression *new_expression) : T_expression(new_location) { expression = new_expression ; }
	virtual ~T_expression_unary() { delete expression ; }
	virtual int is_block(void) const { return expression->is_block() ; }
	} ;

class T_expression_logical_not : public T_expression_unary
	{
public:
	T_expression_logical_not(const T_entity_location &new_location, T_expression *new_expression) : T_expression_unary(new_location, new_expression) {}
	virtual const char *get_name(void) const { return "logical_not" ; }
	virtual void dump(FILE *file) const ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void prepare(T_entity_program *program, FILE *file) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	} ;

class T_expression_bitwise_complement : public T_expression_unary
	{
public:
	T_expression_bitwise_complement(const T_entity_location &new_location, T_expression *new_expression) : T_expression_unary(new_location, new_expression) {}
	virtual const char *get_name(void) const { return "bitwise_complement" ; }
	virtual void dump(FILE *file) const ;
	} ;

class T_expression_pre_increment : public T_expression_unary
	{
public:
	T_expression_pre_increment(const T_entity_location &new_location, T_expression *new_expression) : T_expression_unary(new_location, new_expression) {}
	virtual const char *get_name(void) const { return "pre_increment" ; }
	virtual void dump(FILE *file) const ;
	} ;

class T_expression_pre_decrement : public T_expression_unary
	{
public:
	T_expression_pre_decrement(const T_entity_location &new_location, T_expression *new_expression) : T_expression_unary(new_location, new_expression) {}
	virtual const char *get_name(void) const { return "pre_decrement" ; }
	virtual void dump(FILE *file) const ;
	} ;

class T_expression_minus : public T_expression_unary
	{
public:
	T_expression_minus(const T_entity_location &new_location, T_expression *new_expression) : T_expression_unary(new_location, new_expression) {}
	virtual const char *get_name(void) const { return "minus" ; }
	virtual void dump(FILE *file) const ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void prepare(T_entity_program *program, FILE *file) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	} ;

class T_expression_plus : public T_expression_unary
	{
public:
	T_expression_plus(const T_entity_location &new_location, T_expression *new_expression) : T_expression_unary(new_location, new_expression) {}
	virtual const char *get_name(void) const { return "plus" ; }
	virtual void dump(FILE *file) const ;
	} ;

class T_expression_address : public T_expression_unary
	{
public:
	T_expression_address(const T_entity_location &new_location, T_expression *new_expression) : T_expression_unary(new_location, new_expression) {}
	virtual const char *get_name(void) const { return "address" ; }
	virtual void dump(FILE *file) const ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void prepare(T_entity_program *program, FILE *file) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	} ;

/*class T_expression_access_access : public LINK<T_expression_access_access>
	{
public:
	T_entity_location location ;
	T_expression_access_access(const T_entity_location &new_location) : location(new_location) {}
	virtual ~T_expression_access_access() {} ;
	virtual void dump(FILE *file) const = 0 ;
	} ;*/

class T_expression_identifier_access : public T_expression
	{
public:
	T_expression *expression ;
	T_string identifier ;
	int introspect ;
	int index ;
	const T_object_class *introspect_class ;
	const T_object_class_method *method ;
	const T_object_class_field *field ;
	const T_object_class_value *value ;
	T_expression_identifier_access(const T_entity_location &new_location, T_expression *new_expression, const T_string new_identifier, int new_introspect) : T_expression(new_location), identifier(new_identifier) { expression = new_expression ; introspect = new_introspect ; index = 0 ; introspect_class = NULL ; method = NULL ; field = NULL ; value = NULL ; }
	virtual const char *get_name(void) const { return "identifier_access" ; }
	virtual void dump(FILE *file) const ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual int verify_call_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type, T_expression_call_access *call) ;
	virtual void prepare(T_entity_program *program, FILE *file) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	virtual void prepare_call(T_entity_program *program, FILE *file, const T_expression_call_access *call) ;
	virtual void generate_call(T_entity_program *program, FILE *file, const T_expression_call_access *call) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	} ;

class T_expression_call_base : public T_expression_constructor_arguments
	{
public:
	T_object_class *object_class ;
	const T_constructor *constructor ;
	const T_object_class_method *method ;
	int index ;
	T_expression_call_base(const T_entity_location &new_location) : T_expression_constructor_arguments(new_location) { object_class = NULL ; constructor = NULL ; method = NULL ; index = 0 ; }
	virtual T_type *get_type_expression(void) const { return type ; }
	virtual const char *get_name(void) const { return "call_base" ; }
	virtual void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void prepare(T_entity_program *program, FILE *file) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	} ;

class T_expression_call_access : public T_expression_constructor_arguments
	{
public:
	T_expression *expression ;
	int index ;
	const T_constructor *constructor ;
	T_expression_call_access(const T_entity_location &new_location, T_expression *new_expression) : T_expression_constructor_arguments(new_location) { expression = new_expression ; index = 0 ; constructor = NULL ; }
	virtual const char *get_name(void) const { return "call_access" ; }
	virtual T_type *get_type_expression(void) const { if (constructor == NULL) return NULL ; return type ; }
	virtual void dump(FILE *file) const ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void prepare(T_entity_program *program, FILE *file) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	virtual void generate_test(T_entity_program *program, FILE *file, int jump_if_true, int true_label, int false_label) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	virtual void generate_constructor(T_entity_program *program, FILE *file, const T_string name) ;
	} ;

class T_expression_array_access : public T_expression
	{
public:
	T_expression *expression ;
	LIST<T_expression> expressions ;
	T_expression_array_access(const T_entity_location &new_location, T_expression *new_expression) : T_expression(new_location) { expression = new_expression ; }
	virtual const char *get_name(void) const { return "array_access" ; }
	virtual void dump(FILE *file) const ;
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	} ;

class T_expression_post_increment : public T_expression_unary
	{
public:
	T_expression_post_increment(const T_entity_location &new_location, T_expression *new_expression) : T_expression_unary(new_location, new_expression) {}
	virtual const char *get_name(void) const { return "post_increment" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return FALSE ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	} ;

class T_expression_post_decrement : public T_expression_unary
	{
public:
	T_expression_post_decrement(const T_entity_location &new_location, T_expression *new_expression) : T_expression_unary(new_location, new_expression) {}
	virtual const char *get_name(void) const { return "post_decrement" ; }
	virtual void dump(FILE *file) const ;
	virtual int is_block(void) const { return FALSE ; }
	virtual int verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope, T_type_method *method_type) ;
	virtual void generate(T_entity_program *program, FILE *file, int generate_type) ;
	virtual void generate_instruction(T_entity_program *program, FILE *file) ;
	} ;
